/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.posplus.losspreventiondataimporter.svt;

import com.posplus.lossprevention.APDAOFactory;
import com.posplus.lossprevention.dao.StoresDAO;
import com.posplus.lossprevention.mapping.Cashiers;
import com.posplus.lossprevention.mapping.Registers;
import com.posplus.lossprevention.mapping.Stores;
import com.posplus.lossprevention.mapping.Transactions;
import com.posplus.strack.mapping.RegisterHeader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

/**
 *
 * @author ScottW
 */
public class RegisterHeaderMapper {

    public static List<Transactions> svtToLp(List<RegisterHeader> regHeader, APDAOFactory lpFactory) {
        List<Transactions> result = new ArrayList<Transactions>();
        
        StoresDAO storeDAO = lpFactory.getStoresDAO();
        
        List<Stores> lpStores = storeDAO.findAll();
        Map<String, Stores> storesMap = storesToMap(lpStores);
        
        Iterator<RegisterHeader> iter = regHeader.iterator();
        while(iter.hasNext()){
            RegisterHeader next = iter.next();
            
            try{
                Stores store = storesMap.get("8765");
                if(store == null)
                    throw new RuntimeException("Could not find store 8765");
                
                Registers register = null;
                Iterator<Registers> regIter = store.getRegisterses().iterator();
                while(regIter.hasNext()){
                    Registers nextReg = regIter.next();
                    if(nextReg.getNumber() == next.getId().getRegisterNo()){
                        register = nextReg;
                        break;
                    }
                }
                
                Cashiers cashier = null;
                Iterator<Cashiers> cashIter = store.getCashierses().iterator();
                while(cashIter.hasNext()){
                    Cashiers nextCash = cashIter.next();
                    if(nextCash.getCode().equalsIgnoreCase(next.getId().getEmpNo().toString())){
                        cashier = nextCash;
                        break;
                    }
                }
                
                
                Calendar transactionEnd = next.getDatetime();
                Calendar ringTimeStart = Calendar.getInstance();
                BigDecimal endTimeInMillis = new BigDecimal(transactionEnd.getTimeInMillis());
                BigDecimal ringTimeStartInMillis = endTimeInMillis.subtract(next.getTimeon());
                ringTimeStart.setTimeInMillis(ringTimeStartInMillis.longValue());
                Calendar ringTimeEnd = null;
                if(next.getRingsPerMin().compareTo(new BigDecimal("0")) > 0)
                    ringTimeEnd = estimateRingTimeEnd(ringTimeStart, next.getRingsPerMin(), next.getTotItems());
                
                if(register != null && store != null && cashier != null && ringTimeStart != null &&
                        ringTimeEnd != null && transactionEnd != null && next.getId().getTransNo() != null){
                    Transactions trans = new Transactions(register, store, cashier, next.getProcDate().getTime(), ringTimeStart, ringTimeEnd, transactionEnd, next.getId().getTransNo());                
                    result.add(trans);
                }
            }catch(RuntimeException ex){
                Logger.getLogger(RegisterHeaderMapper.class).warn(ex + ": " + next);
            }
        }
        
        return result;
    }
    
    private static Calendar estimateRingTimeEnd(Calendar transactionStart, BigDecimal ringsPerMinute, BigDecimal numItems){
        Calendar result = Calendar.getInstance();
        
        BigDecimal totalRingTime = numItems.divide(ringsPerMinute, 10, RoundingMode.HALF_UP).multiply(new BigDecimal("60"));
        
        result.setTimeInMillis(transactionStart.getTimeInMillis() + totalRingTime.longValue());
        
        return result;
    }

    private static Map<String, Stores> storesToMap(List<Stores> lpStores) {
        Map<String, Stores> result = new HashMap<String, Stores>();
        
        Iterator<Stores> iter = lpStores.iterator();
        while(iter.hasNext()){
            Stores next = iter.next();
            result.put(next.getCode(), next);
        }
        
        return result;
    }
    
}
